home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / doc / debug.doc < prev    next >
Encoding:
Text File  |  1994-08-25  |  24.0 KB  |  784 lines  |  [TEXT/ttxt]

  1.  
  2. The Mindy Debugger
  3.  
  4. Copyright (c) 1994  Carnegie Mellon University
  5. All rights reserved.  Refer to the end of this document for precise terms of
  6. use. 
  7.  
  8.  
  9.  
  10. Introduction
  11.  
  12. When something goes wrong with your program, Mindy drops into the debugger.
  13. From the debugger, you can examine the stack, print out variables, evaluate
  14. expressions, and do various other things that can be helpful in figuring out
  15. what went wrong.
  16.  
  17. For example, if you did not define a method for main, after starting Mindy
  18. you would see something like the following:
  19.  
  20.     No applicable methods for main with arguments #[]
  21.  
  22.     thread [0] D   main
  23.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  24.     mindy> 
  25.  
  26. The first line is the error message.  The second line tells you about the
  27. thread that encountered the error.  For more information about threads see
  28. Section Threads.  The third line tells you about the current stack frame for
  29. the thread; in this example, the last function called, which is at the top
  30. of the stack, is the invoke-debugger function.  It was called with one
  31. argument, a <simple-error>.
  32.  
  33. The following sections discuss the various commands provided by the
  34. debugger.  As a general rule, you can invoke a command by typing at least a
  35. unique prefix of its name.  There are three commonly used commands for which
  36. a single letter suffices, regardless of all other command names:
  37.    (d)own
  38.    (l)ocals
  39.    (c)ontinue
  40.  
  41. Throughout this document, some examples build on previous examples, even
  42. when those previous examples come from previous sections of the document.
  43. If there is a reference to the "previous example", then please look to the
  44. previous section's text.
  45.  
  46.  
  47.  
  48. Stack Manipulation Commands
  49.  
  50. The Mindy debugger offers a few commands for moving up and down the stack.
  51. The two most common commands are "up" and "down".  Mindy considers the most
  52. recently called function to be at the top of the stack and the least
  53. recently called function to be at the bottom of the stack.  Hence, moving
  54. down the stack moves you from a callee to its caller.  For example, if you
  55. were to type "down" after the previous example, you would see something like
  56. the following:
  57.  
  58.     mindy> down
  59.     fp 0x10034078: error({<simple-error> 0x1023fa91}, #[], #())
  60.     /afs/cs.cmu.edu/project/gwydion/mindy/src/runtime/cond.dylan
  61.     132    signal(cond);
  62.     mindy> 
  63.  
  64. The first line tells you about the new current frame, which is a call to the
  65. error function.  For a function written in Dylan, as opposed to a built-in
  66. function provided by Mindy, the debugger tries to show the line of source
  67. code associated with the current frame.  If the debugger could not find the
  68. source file, it still prints the line number from the source file.
  69.  
  70. While moving down the stack, you might have expected to see a call to the
  71. signal function before seeing a call to the error function.  This does not
  72. happen because signal tail calls invoke-debugger.  When a function tail
  73. calls another function, the callee reuses the current stack frame of the
  74. caller.
  75.  
  76. In addition to the "up" and "down" commands, you can move to a specified
  77. stack frame using the "frame" command.  The debugger numbers stack frames
  78. starting at zero at the top of the stack.  Currently, the debugger does not
  79. print frame numbers when it prints frame information, so moving with the
  80. "frame" command is only useful as a rough thumb bar.  The following is an
  81. example of using this command to go to the top of the stack:
  82.  
  83.     mindy> frame 0
  84.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  85.     mindy> 
  86.  
  87. If you use the "frame" command without supplying a frame number, the command
  88. prints the current frame's information.  This is useful if the description
  89. of the current frame has scrolled off the screen, and you want to see it
  90. again.
  91.  
  92. You can view the entire stack by using the "backtrace" command.  The current
  93. frame stays the same, but the "backtrace" command always shows the entire
  94. stack from the top to the bottom.  The following is example output from this
  95. command:
  96.  
  97.     mindy> backtrace
  98.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  99.     fp 0x10034078: error({<simple-error> 0x1023fa91}, #[], #()) \
  100.     [/afs/cs.cmu.edu/project/gwydion/mindy/src/runtime/cond.dyla\
  101.     n, line 132]
  102.     fp 0x10034058: main()
  103.     mindy> 
  104.  
  105.  
  106.  
  107. Examining variables
  108.  
  109. The "locals" command prints the value for every local variable in the
  110. function associated with the current frame.  If you were at the frame for
  111. the error call in the previous example, using the "locals" command would
  112. look like the following:
  113.  
  114.     mindy> locals
  115.     noise: #[]
  116.     cond: {<simple-error> 0x1023fa91}
  117.     mindy> 
  118.  
  119. You can use the "print" command to print a specific local variable.  The
  120. following is an example of printing the "cond" variable shown in the
  121. previous sample output:
  122.  
  123.         mindy> print cond
  124.     $0={<simple-error> 0x1023fa91}
  125.     mindy> 
  126.  
  127. The "print" command can also print the value of global variables:
  128.  
  129.     mindy> print size
  130.     $1={<generic-function> size}
  131.     mindy> 
  132.  
  133. For information on the labels the debugger assigns to values (that is, the
  134. $N identifications), see Section Debugger Variables.
  135.  
  136. If the debugger does not find a local variable with the name you supplied,
  137. the debugger looks for a global variable by that name in the current library
  138. and module.  For more information about libraries and modules, see Section
  139. Libraries and Modules.  For more information about the "print" command, see
  140. Section Evaluating Expressions.
  141.  
  142.  
  143.  
  144. Libraries and Modules
  145.  
  146. When evaluating expressions, the debugger uses the "current library" and
  147. "current module".  When the debugger starts up, it guesses at what library
  148. and module to make current.  If you want to access a global variable from
  149. another module or library, you first make another module or library be the
  150. current one with the "library" or "module" command.  If you invoke the
  151. "library" command without an argument, it lists the available libraries and
  152. tells you which one is the current one.  If you invoke the "library" command
  153. with an argument, the debugger makes that library be the current library.
  154. In the same way, the "module" command either lists the modules of the
  155. current library, or it selects another module be the current module.  The
  156. following are examples of using the "library" command:
  157.  
  158.     mindy> library
  159.     Dylan-User
  160.     Dylan
  161.  
  162.     Current library is Dylan
  163.     mindy> library dylan-user
  164.     mindy> 
  165.  
  166. The following is an example of using the "module" command after having just
  167. switched to the Dylan-User library:
  168.  
  169.     mindy> module
  170.        Dylan-User
  171.      i File-Descriptors
  172.      i Threads
  173.      i Extensions
  174.      i System
  175.      i Dylan
  176.  
  177.     The current module is Dylan-User
  178.     mindy> 
  179.  
  180. The "i" in the second column indicates that those modules are being imported
  181. into the Dylan-User library as opposed to being defined there.  The "module"
  182. command also indicates which modules are exported from the current library.
  183. For example, if you were to switch to the Dylan library, the module command
  184. would produce the following output:
  185.  
  186.     mindy> library dylan
  187.     mindy> module
  188.        Dylan-User
  189.     x  File-Descriptors
  190.     x  Threads
  191.        Builtin-Stuff
  192.     x  Extensions
  193.     x  System
  194.     x  Dylan
  195.  
  196.     The current module is Dylan-User
  197.     mindy> 
  198.  
  199. The "x" in the first column indicates that those modules are exported.
  200. There were no x's in the listing of modules in the Dylan-User library
  201. because no modules are exported from the Dylan-User library.  There were no
  202. i's in the listing of modules for the Dylan library because the Dylan
  203. library does not import any modules.
  204.  
  205. Whenever you change libraries with the "library" command, the debugger
  206. resets the current module to the Dylan-User module.  This is because the
  207. debugger needs to make a module current in the new library, and every
  208. library has a Dylan-User module.
  209.  
  210.  
  211.  
  212. Evaluating Expressions
  213.  
  214. The "print" command can evaluate simple expressions and print their results.
  215. The following is an example:
  216.  
  217.     mindy> print list(1, 2, 3)
  218.     $2=#(1, 2, 3)
  219.     mindy> print vector(4, 5, 6)
  220.     $3=#[4, 5, 6]
  221.     mindy>
  222.  
  223. The "print" command evaluates the variable "list" and then invokes that
  224. function with the arguments 1, 2, and 3.  The debugger labels values printed
  225. with a dollar sign and a number, and you can use these in later expressions.
  226. For more information on these, see Section Debugger Variables.
  227.  
  228. The expressions that the debugger accepts are limited.  An expression can be
  229. one of the following:
  230.   - one of the following literals:
  231.        decimal number (47)
  232.        keyword (foo:)
  233.        string ("foo")
  234.        #t
  235.        #f
  236.   - a variable name.
  237.   - a debugger variable (for example, $5).
  238.   - a function call (for example, foo(a, b) and bar(c, quux: 3))
  239.   - the address, in hexidecimal (C format, not Dylan), of a valid dylan
  240.     object (for example, 0x102050b1).  Note: use this feature with care, as
  241.     a mistyped address can cause Mindy to dump core.
  242.  
  243. If the expression results in multiple values, all the values are printed on
  244. a single line:
  245.  
  246.     mindy> print values(1, 2, 3)
  247.     $4=1, $5=2, $6=3
  248.  
  249. If an error occurs while the debugger is evaluating the expression, it
  250. prints the error message, aborts the "print" command, and returns to the
  251. debugger prompt.  The following is an example of this situation:
  252.  
  253.     mindy> print error("oops")
  254.     invocation failed:
  255.       oops
  256.     mindy> 
  257.  
  258. The "call" command is like the "print" command, but the "call" command does
  259. not handle errors by aborting.  When you use the "call" command, and the
  260. expression causes an error, the debugger returns to its prompt, but any
  261. stack frames that were created due to the "call" command are now visible for
  262. inspection.  The following is an example of using the "call" command:
  263.  
  264.     mindy> call error("oops")
  265.  
  266.     oops
  267.  
  268.     thread [0] D   main
  269.     fp 0x100341f4: invoke-debugger({<simple-error> 0x102456b1})
  270.     mindy> 
  271.  
  272. The "print" and "call" commands can also evaluate multiple, comma-separated
  273. expressions:
  274.  
  275.     mindy> print 1, 2, 3
  276.     $7=1
  277.     $8=2
  278.     $9=3
  279.     mindy> 
  280.  
  281.  
  282.  
  283. Debugger Variables
  284.  
  285. The "print" or "call" commands label every value printed, and these labels
  286. identify "debugger variables".  You can use these identifers in later
  287. expressions to refer to previously computed values.  The following is an
  288. example:
  289.  
  290.     mindy> p list(1, 2, 3)
  291.     $4=#(1, 2, 3)
  292.     mindy> p second($4)
  293.     $5=2
  294.     mindy> 
  295.  
  296. The notation "$-N" provides a dynamic alternative to identifying debugger
  297. variables.  This notation refers to previously printed values by using N as
  298. a count from the most recently printed value to the least recently printed.
  299. The counting begins at one.
  300.  
  301.     mindy> print a:, b:, c:, d:
  302.     $12=a
  303.     $13=b
  304.     $14=c
  305.     $15=d
  306.     mindy> print $-1, $-2, $-3, $-4
  307.     $16=d
  308.     $17=c
  309.     $18=b
  310.     $19=a
  311.     mindy> 
  312.  
  313. You can use "$" as a shorthand for "$-1", and "$$" for "$-2":
  314.  
  315.     mindy> p 2
  316.     $20=2
  317.     mindy> p list($, 4)
  318.     $21=#(2, 4)
  319.     mindy> p list($$, 6)
  320.     $22=#(2, 6)
  321.     mindy> 
  322.  
  323. Mindy keeps references to all debugger variables to prevent them from being
  324. garbage collected.  If you no longer care about previously printed values,
  325. you might want to use the "flush" command to get rid of them:
  326.  
  327.     mindy> flush
  328.     Flushed all debugger variables.
  329.     mindy> p $0
  330.     invocation failed:
  331.       No debug variable $0
  332.     mindy> p list(a:, b:, c:)
  333.     $0=#(a, b, c)
  334.     mindy> 
  335.     
  336. You can use "$aN" notation to refer to the arguments passed to the function
  337. call associated with the current stack frame.  N is the argument number,
  338. counting from zero.  The following is an example:
  339.  
  340.     mindy> frame
  341.     fp 0x10034078: error({<simple-error> 0x1023fa91}, #[], #())
  342.     /afs/cs.cmu.edu/project/gwydion/mindy/src/runtime/cond.dylan
  343.     132    signal(cond);
  344.     mindy> p $a0
  345.     $1={<simple-error> 0x1023fa91}
  346.     mindy> p $a1
  347.     $2=#[]
  348.     mindy> p $a2
  349.     $3=#()
  350.     mindy> 
  351.  
  352. The "$aN" notation does not identify a debugger variable, and the debugger
  353. does not have to create storage for these values because they are already
  354. stored on the call stack.  The "flush" command has no effect on argument
  355. values.
  356.  
  357.  
  358.  
  359. Restarts and Returning
  360.  
  361. This section discusses invoking Dylan restart handlers and returning values
  362. for conditions whose recovery protocols allow returning.  If you do not know
  363. what these are, see the Dylan Interim Reference Manual.
  364.  
  365. The debugger has commands that allow you to try to continue executing your
  366. program.  The most common way to continue execution is to invoke a Dylan
  367. restart.  To either list the available restarts or invoke a restart, you use
  368. the "restart" command:
  369.  
  370.     mindy> call cerror("go on", "oops")
  371.  
  372.     oops
  373.  
  374.     thread [0] D   main
  375.     fp 0x1003428c: invoke-debugger({<simple-error> 0x10245361})
  376.     mindy> restart
  377.     0 [{class <simple-restart>}]: go on
  378.     1 [{class <abort>}]: Blow off call
  379.     mindy> restart 0
  380.     $0=#f
  381.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  382.     mindy> 
  383.  
  384. In this example, the restart command lists two restarts.  The cerror
  385. function establishes the "go on" restart (numbered 0).  The "call" command
  386. establishes the "Blow off call" restart (numberd 1).  The "restart 0"
  387. command caused cerror to return #f, which the "call" command printed.
  388.  
  389. The "abort" command invokes the first restart that handles <abort> restarts.
  390. The following is an example of this command:
  391.  
  392.     mindy> call error("oops")
  393.  
  394.     oops
  395.  
  396.     thread [0] D   main
  397.     fp 0x100341fc: invoke-debugger({<simple-error> 0x10241d49})
  398.     mindy> abort
  399.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  400.     mindy> 
  401.  
  402. If Mindy entered the debugger due to a condition that allows returning as
  403. part of its recovery protocol, then you can use the "return" command.  For
  404. example, consider the <ignorable-error> condition that is a subclass of
  405. <error> and that allows returning as part of its recovery protocol.  The
  406. following example shows returning from the signalling of this condition:
  407.  
  408.     mindy> call signal(make(<ignorable-error>))
  409.  
  410.     {<ignorable-error> 0x10247759}
  411.  
  412.     thread [0] D   main
  413.     fp 0x100341d4: invoke-debugger({<ignorable-error> 0x10247759})
  414.     mindy> restart
  415.     0 [{class <abort>}]: Blow off call
  416.  
  417.     Returning is allowed:
  418.       ignore it.
  419.     mindy> return
  420.     $0=#f
  421.     fp 0x10034090: invoke-debugger({<simple-error> 0x10244831})
  422.     mindy> 
  423.  
  424.  
  425.  
  426. Interrupting and Single Stepping
  427.  
  428. Sometimes it is useful to interrupt your program to see where it is
  429. currently executing.  consider the following program as an example:
  430.  
  431.     module: Dylan-User
  432.  
  433.     define method main (#rest noise)
  434.       foo(#t);
  435.     end;
  436.  
  437.     define method foo (x)
  438.       if (x)
  439.         foo(#f);
  440.       else
  441.         foo(#t);
  442.       end;
  443.     end;
  444.  
  445. If you were to run this program and then interrupt it, you would see output
  446. similar to the following:
  447.  
  448.     ^C
  449.     Interrupted
  450.     thread [0] R   main
  451.     fp 0x10034060: foo(#f, #())
  452.     foo.dylan
  453.     8    if (x)
  454.     mindy> 
  455.  
  456. After interrupting the program you have the full debugger at your disposal,
  457. as if an error had occurred.  Additionally, you can use the "continue"
  458. command to resume execution:
  459.  
  460.     mindy> continue
  461.  
  462. You can also use the "step" command to advance line by line through your
  463. program.  When stepping, if the debugger encounters a function call, it
  464. descends into that function and steps line by line.  The following is an
  465. example:
  466.  
  467.     ^C
  468.     Interrupted
  469.     thread [0] R   main
  470.     fp 0x10034060: foo(#f, #())
  471.     foo.dylan
  472.     8    if (x)
  473.     mindy> step
  474.     foo.dylan
  475.     11    foo(#t)
  476.     mindy> step
  477.     foo.dylan
  478.     8    if (x)
  479.     mindy> step
  480.     foo.dylan
  481.     9    foo(#f)
  482.     mindy> step
  483.     foo.dylan
  484.     8    if (x)
  485.     mindy> 
  486.  
  487.  
  488.  
  489. Breakpoints
  490.  
  491. The debugger has a primitive facility for setting breakpoints in methods
  492. written in Dylan, as opposed to built-in methods provided by Mindy.  The
  493. "breakpoint" command takes two arguments, a reference to a method in which
  494. to install the breakpoint, and the line number at which to install the
  495. breakpoint.  For example, consider the following program:
  496.  
  497.     module: dylan-user
  498.  
  499.     define constant foo =
  500.       method ()
  501.         puts("this is a test\n");
  502.         puts("of breakpoints.\n");
  503.         #f;
  504.       end;
  505.  
  506. If you were to put a breakpoint at line 6 (the second puts), Mindy would
  507. produce output similar to the following:
  508.  
  509.     mindy> break foo, 6
  510.     breakpoint 1 installed in {anonymous <byte-method> 0x10243d31\
  511.     #()} at line 6 (pc 47)
  512.     mindy> call foo()
  513.     this is a test
  514.     Breakpoint
  515.     thread [0] R   main
  516.     fp 0x100341dc: {anonymous <byte-method> 0x10243d31 #()}(#())
  517.     foo.dylan
  518.     6    puts("of breakpoints.\n");
  519.     mindy> 
  520.  
  521. The "continue" and "step" commands can be used to continue execution (see
  522. Section Interrupting and Single Stepping):
  523.  
  524.  
  525.     mindy> step
  526.     of breakpoints.
  527.     foo.dylan
  528.     7    #f;
  529.     mindy> c
  530.     $0=#f
  531.     fp 0x10034090: invoke-debugger({<simple-error> 0x10243e49})
  532.     mindy> 
  533.  
  534. The breakpoint command evaluates its first argument, so you can use an
  535. arbitrary expression for the function.  For example, you could use
  536. find-method to extract a specific method from a generic function and insert
  537. a breakpoint in that method:
  538.  
  539.         mindy> br find-method(size, list(<table>)), 886
  540.     breakpoint 1 installed in {<byte-method> size #({class <table>})}\
  541.     at line 886 (pc 35)
  542.     mindy>
  543.  
  544.  
  545.  
  546.  
  547. The breakpoint command with no arguments lists the currently installed
  548. breakpoints:
  549.  
  550.     mindy> breakpoint
  551.     id  where
  552.      1  pc 47 in {<component> 0x10204ea9}
  553.     mindy> 
  554.  
  555. The "delete N" command removes a breakpoint, where N is is the breakpoint ID
  556. reported in the "breakpoint" listing.
  557.  
  558. Sometimes the Mindy compiler has to split a single top level form into
  559. multiple methods.  When this happens, the debugger cannot always figure out
  560. where to insert your breakpoint.  Consider the following program:
  561.  
  562.     module: dylan-user
  563.  
  564.     define constant foo =
  565.       method ()
  566.         block (exit)
  567.           puts("this is a test\n");
  568.           puts("of breakpoints.\n");
  569.           #f;
  570.         end;
  571.       end;
  572.  
  573. When this program is compiled, the compiler has to put the contents of the
  574. block in a seperate method.  Because of this, if you were to try to insert a
  575. breakpoint at line 7 it wouldn't work:
  576.  
  577.     mindy> break foo, 7
  578.     {anonymous <byte-method> 0x10243f59 #()} does not span line n\
  579.     umber 7 
  580.     mindy>
  581.  
  582. To insert a breakpoint into this method, you need to use the "disassemble"
  583. command.  It disassembles a method and all Mindy-generated methods that
  584. might be associated with that method.  For example:
  585.  
  586.     mindy> disassemble foo
  587.     anonymous component, from "foo.dylan"
  588.     5        block (exit)
  589.         47: b0             push    function catch
  590.         48: 21             push    const(1)    {<method-info\
  591.     > 0x10205149}
  592.         49: b2             push    function list
  593.         50: a3             push    value <object>
  594.         51: 91             call    nargs = 1, for single
  595.         52: 0e             push    #()
  596.         53: 10             push    #t
  597.         54: 06             make-method
  598.         55: 71             call    nargs = 1, tail
  599.  
  600.     {<method-info> 0x10205149}, anonymous component, from "foo.dy\
  601.     lan"
  602.     5        block (exit)
  603.         51: 31             push    arg(1)
  604.         52: 20             push    const(0)    {<method-info\
  605.     > 0x102050b1}
  606.         53: b1             push    function list
  607.         54: 90             call    nargs = 0, for single
  608.         55: 0e             push    #()
  609.         56: 10             push    #t
  610.         57: 06             make-method
  611.         58: 60             pop    local(0)
  612.     6          puts("this is a test\n");
  613.         59: b2             push    function puts
  614.         60: 23             push    const(3)    "this is a te\
  615.     st\n"
  616.         61: 81 00          call    nargs = 1, for 0
  617.     7          puts("of breakpoints.\n");
  618.         63: b2             push    function puts
  619.         64: 24             push    const(4)    "of breakpoin\
  620.     ts.\n"
  621.         65: 81 00          call    nargs = 1, for 0
  622.     8          #f;
  623.         67: 11             push    #f
  624.         68: 02             return single
  625.  
  626.     {<method-info> 0x102050b1}, exit component, from "foo.dylan"
  627.     5        block (exit)
  628.         39: b0             push    function apply
  629.         40: a1             push    value throw
  630.         41: 30             push    arg(0)
  631.         42: 32             push    arg(2)
  632.         43: 73             call    nargs = 3, tail
  633.     mindy> 
  634.  
  635. As you can see, the function foo has been split into three methods.  The
  636. first one corresponds to the part of foo that is outside the block.  The
  637. second one corresponds to the code inside the block.  And the third one
  638. corresponds to the exit function established by the block.  Look for the
  639. second method which spans line 7.  The following shows how to install the
  640. breakpoint:
  641.  
  642.     mindy> br 0x10205149, 7
  643.     breakpoint 1 installed in {<method-info> 0x10205149} at line \
  644.     7 (pc 63)
  645.     mindy> call foo()
  646.     this is a test
  647.     Breakpoint
  648.     thread [0] R   main
  649.     fp 0x100341f8: {anonymous <byte-method> 0x10245f41 #({class <\
  650.     object>})}({<catch> 0x10245f81}, #())
  651.     foo.dylan
  652.     7    puts("of breakpoints.\n");
  653.     mindy> c
  654.     of breakpoints.
  655.     $0=#f
  656.     fp 0x10034090: invoke-debugger({<simple-error> 0x10244071})
  657.     mindy> 
  658.  
  659.  
  660.  
  661. Threads
  662.  
  663. Normally, there is only one thread of execution, in which case you won't
  664. need any of the commands in this section.  When you debug a multi-threaded
  665. program, these commands become very useful.  The "thread" command either
  666. lists the available threads or switches between them, depending on how you
  667. invoke it.  For example:
  668.  
  669.     mindy> p spawn-thread(foo:, curry(break, "Thread foo"))
  670.     $0={<thread> 0x10243f49}
  671.     mindy> p spawn-thread(bar:, curry(break, "Thread bar"))
  672.     $1={<thread> 0x10246f19}
  673.     mindy> thread
  674.     c [0] D   main
  675.       [1] R   foo
  676.       [2] R   bar
  677.     mindy> 
  678.  
  679. In this example, the "thread" command lists three threads: the original
  680. "main" thread and the two threads you just created.  The "c" in the first
  681. column indicates which thread the debugger is currently examining.  The
  682. "[N]" indicates the thread ID for each thread.  The "D" and "R" designations
  683. indicate the status of each thread.  The "main," "foo," and "bar" labels are
  684. the debug-names passed as the first argument to spawn-thread.
  685.  
  686. The different thread status codes are as follows:
  687.  
  688.      STATUS    MEANING
  689.     D    current thread the debugger is examining
  690.     R    running/runable
  691.     S    suspended
  692.     B    blocked on a lock
  693.     W    waiting for an event
  694.  
  695. Giving the "thread" command an argument causes the debugger to examine
  696. another thread.  You can designate threads with either its numeric ID or the
  697. debug-name passed to spawn-thread:
  698.  
  699.     mindy> thread foo
  700.     thread [1] R   foo
  701.     fp 0x102550bc: {anonymous <byte-method> 0x102443d9 #({class <\
  702.     object>})}({<catch> 0x10244421}, #(), {<value-cell> 0x1024436\
  703.     9}, {<breakpoint> 0x102441e1})
  704.     /afs/cs.cmu.edu/project/gwydion/mindy/src/runtime/cond.dylan
  705.     212    init-arguments: list(format-string: "Continue from br\
  706.     eak"))
  707.     mindy> thread 0
  708.     thread [0] D   main
  709.     fp 0x10034090: invoke-debugger({<simple-error> 0x1023fa91})
  710.     mindy> 
  711.  
  712. Sometimes it is useful to temporarily disable some threads while debugging
  713. other threads.  The "disable <thread-id-or-name>" command disables
  714. (suspends) the indicated thread, and the "enable" command allows a thread to
  715. run again:
  716.  
  717.     mindy> disable foo
  718.     [1] S 1 foo
  719.     mindy> enable foo
  720.     [1] R   foo
  721.     mindy>
  722.  
  723. In this example, The status of the foo thread changes from R (runnable) to S
  724. (suspended) when it is disabled.
  725.  
  726. If you repeatedly use the "disable" command on the same thread, then the
  727. "enable" command must be used the same number of times to before the
  728. thread's status changes to R. The 1 after the S above is the number of times
  729. the thread foo has been disabled.
  730.  
  731. When a thread is suspended, the "continue" and "step" commands do not
  732. advance the thread's execution.  The "disable" and "enable" commands can
  733. help you find thread synchronization problems by allowing you to explicitly
  734. control when each thread runs.
  735.  
  736. Invoking the "disable" or "enable" command with no argument affects the
  737. current thread the debugger is examining.
  738.  
  739. The "kill <thread-id-or-name>" command kills the indicated thread.
  740.  
  741.  
  742.  
  743. Miscellaneous Commands
  744.  
  745. The "help" command prints a one line summary of all the debugger commands.
  746.  
  747. The "quit" command causes Mindy to exit without executing any of the on-exit
  748. hooks.  If you want the on-exit hooks to run, you should invoke the exit
  749. function with the print command:
  750.    mindy> print exit()
  751.  
  752. The "tron" command turns on an internal trace facility that prints the
  753. arguments and results for every function call.  The "troff" command turns
  754. this off.
  755.  
  756. The "error" command repeats the error message for the condition that caused
  757. this thread to drop into the debugger.
  758.  
  759. The "gc" command invokes the garbage collector.
  760.  
  761.  
  762.  
  763. Copyright and Terms of Use
  764.  
  765. Copyright (c) 1994  Carnegie Mellon University
  766. All rights reserved.  
  767.  
  768. Use and copying of this software and preparation of derivative works based on
  769. this software are permitted, including commercial use, provided that the
  770. following conditions are observed:
  771.  
  772. 1. This copyright notice must be retained in full on any copies and on
  773.    appropriate parts of any derivative works.
  774. 2. Documentation (paper or online) accompanying any system that incorporates
  775.    this software, or any part of it, must acknowledge the contribution of the
  776.    Gwydion Project at Carnegie Mellon University.
  777.  
  778. This software is made available "as is".  Neither the authors nor Carnegie
  779. Mellon University make any warranty about the software, its performance, or
  780. its conformity to any specification.
  781.  
  782. Bug reports, questions, comments, and suggestions should be sent by E-mail to
  783. the Internet address "gwydion-bugs@cs.cmu.edu".
  784.